package com.haide.channel.pro.exception;

import java.text.MessageFormat;

/**
 * 渠道-基础异常类
 * <p>
 * 1.创建宝付订单号
 * </p>
 *
 * @author : wukong
 * @version : 1.0.0
 * @date : 2018/6/27
 */
public class BaseException extends RuntimeException {

    /**  */
    private static final long serialVersionUID = 1279879878978686L;
    /**
     * 错误信息模板
     */
    private final static String MSG_TEMPLATE = "错误码:{0}, 描述:{1}, 异常信息:{2}";
    /**
     * 错误码信息
     */
    private ErrorCode errorCode;
    /**
     * 除了错误码本身描述的提示信息外，额外补充的信息
     */
    private String extraMsg;

    /**
     * 提供错误码和异常源构造异常
     *
     * @param errorCode 异常码
     * @param cause     异常原因
     * @throws NullPointerException <code>errorCode</code>不能为空，否则抛出异常
     */
    public BaseException(ErrorCode errorCode, Throwable cause) {
        this(errorCode, null, cause);
    }

    /**
     * 设置除了错误码本身描述的提示信息外，额外补充的信息
     * <p/>
     * 当错误码本身只是比较模糊的提示下，可以额外补充其他信息
     *
     * @param extraMsg 额外补充的信息
     */
    public BaseException(ErrorCode errorCode, String extraMsg, Throwable cause) {
        super(getMessage(errorCode, extraMsg), cause);
        this.errorCode = errorCode;
        this.extraMsg = extraMsg;
    }

    /**
     * 提供异常码构造异常
     *
     * @param errorCode 异常码异常码 *
     * @throws NullPointerException <code>errorCode</code>不能为空，否则抛出异常
     */
    public BaseException(ErrorCode errorCode) {
        this(errorCode, null, null);
    }

    /**
     * 设置除了错误码本身描述的提示信息外，额外补充的信息
     * <p/>
     * 当错误码本身只是比较模糊的提示下，可以额外补充其他信息
     *
     * @param extraMsg 额外补充的信息
     */
    public BaseException(ErrorCode errorCode, String extraMsg) {
        this(errorCode, extraMsg, null);
    }

    /**
     * 参数信息替换
     *
     * @param errorCode    错误编码
     * @param extraMessage 错误描述
     * @return 返回错误描述信息
     */
    private static String getMessage(ErrorCode errorCode, String extraMessage) {
        extraMessage = (null != extraMessage) ? extraMessage : "";
        return formatMsg(MSG_TEMPLATE, errorCode.getErrorCode(), errorCode.getErrorDesc(), extraMessage);
    }

    public static String formatMsg(String msgTemplate, Object... positionValues) {

        try {
            return MessageFormat.format(msgTemplate, positionValues);
        } catch (Exception e) {
            StringBuilder buf = new StringBuilder("资源信息占位符替换异常，占位符参数信息：");
            for (int i = 0; i < positionValues.length; i++) {
                buf.append(" arg[" + i + "]=" + positionValues[i]);
            }
        }
        return msgTemplate;
    }

    /**
     * 获得异常码信息
     *
     * @return ErrorCode
     */
    public ErrorCode getErrorCode() {
        return errorCode;
    }

    /**
     * 返回除了错误码本身描述的提示信息外，额外补充的信息
     *
     * @return the extraMsg
     */
    public String getExtraMsg() {
        return extraMsg;
    }

    /**
     * 设置除了错误码本身描述的提示信息外，额外补充的信息
     *
     * @param extraMsg the extraMsg to set
     */
    public void setExtraMsg(String extraMsg) {
        this.extraMsg = extraMsg;
    }

}
